//package hello.javaConfig;
//
//import org.apache.tomcat.jdbc.pool.DataSource;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
//import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
//import org.springframework.security.config.annotation.web.builders.HttpSecurity;
//import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
//import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
//import org.springframework.security.core.session.SessionRegistry;
//import org.springframework.security.core.session.SessionRegistryImpl;
//import org.springframework.security.crypto.codec.Hex;
//import org.springframework.security.crypto.codec.Utf8;
//import org.springframework.security.crypto.password.StandardPasswordEncoder;
//import org.springframework.security.web.authentication.session.ConcurrentSessionControlAuthenticationStrategy;
//import org.springframework.security.web.session.HttpSessionEventPublisher;
//
//import java.nio.ByteBuffer;
//import java.nio.CharBuffer;
//import java.nio.charset.CharacterCodingException;
//import java.nio.charset.Charset;
//import java.security.MessageDigest;
//import java.security.NoSuchAlgorithmException;
//import java.util.Arrays;
//import java.util.UUID;
//
///**
// * @Author hiberk
// * @Date 2017/7/31 9:20
// * @EnableWebSecurity: 禁用Boot的默认Security配置，配合@Configuration启用自定义配置（需要扩展WebSecurityConfigurerAdapter）
// * @EnableGlobalMethodSecurity(prePostEnabled = true): 启用Security注解，例如最常用的@PreAuthorize
// * configure(HttpSecurity): Request层面的配置，对应XML Configuration中的<http>元素
// * configure(WebSecurity): Web层面的配置，一般用来配置无需安全检查的路径
// * configure(AuthenticationManagerBuilder): 身份验证配置，用于注入自定义身份验证Bean和密码校验规则
// */
//@Configuration
//@EnableWebSecurity //开启security @Configuration、@EnableGlobalAuthentication、@Import
//@EnableGlobalMethodSecurity(prePostEnabled = true) //支持AOP级别的方法 @PreAuthorized注解支持
//public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
//
//    @Autowired
//    private DataSource dataSource;
//
//    @Override
//    protected void configure(HttpSecurity http) throws Exception {
//        //路由策略及权限的简单控制
//        http.authorizeRequests()
//                .antMatchers("/message").access("hasRole('ROLE_ANONYMOUS')")
//                .antMatchers("/admin").access("hasRole('ROLE_ADMIN')")
//                .antMatchers("/welcome").access("hasRole('ROLE_USER')")
//                //配置session固化 防止session攻击 同时限制一个用户最多只有一个session
//                .and().sessionManagement().sessionFixation().migrateSession().maximumSessions(1).maxSessionsPreventsLogin(false)
//                //配置session监听和过期跳转路径。可以统计在线人数
//                .expiredUrl("/indexLogin?error=session").sessionRegistry(sessionRegistry())
//                .and()
//                //启用savedRequest  核心是SecurityContextHolderAwareRequestFilter
//                .and().servletApi()
//                .and().formLogin()
//                //登录页的请求地址 注意：如果自定义了登录页，那么必须指定登录请求的认证url
//                .loginPage("/indexLogin").permitAll()
//                //为security权限拦截器配置登录页的路径
//                .loginProcessingUrl("/validateLogin")
//                .failureUrl("/indexLogin?error=login")
//                .defaultSuccessUrl("/admin")
//                .and().logout().logoutSuccessUrl("/indexLogin").logoutUrl("/j_spring_security_logout").deleteCookies("remember-me").deleteCookies("JSESSIONID")
//                .invalidateHttpSession(true)
//                .and().anonymous().principal("Guest")
//                .and().csrf();
//        super.configure(http);
//    }
//
//
//
//    @Autowired
//    protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
//        //基于内存的认证
//        auth.inMemoryAuthentication()
//                .withUser("Brave").password("123").roles("ADMIN");
////        auth.inMemoryAuthentication()
////                .withUser("admin").password("123").roles("ADMIN","USER");
//        //jdbc验证 返回的权限role必须以ROLE开头的结果集   权限要加前缀  enabled: 1为true
//        auth.jdbcAuthentication().dataSource(dataSource)
//                //查询语句的返回结果必须和下面的保持一致
//                .usersByUsernameQuery("select username,password,enabled from authority_users where username = ?")
//                //权限查询语句的 结果集中列必须在第二列。因为其实现方式为:rs.getString(2) 并且返回的权限 均是以ROLE_ 为前缀.
//                //如果前面配置的是权限，这里需要对应的权限。否则就是角色
//                .authoritiesByUsernameQuery("select u.username,role.role from authority_role role,authority_users u where u.username = ?" +
//                        " and u.id=role.u_id")
//                //盐值加密
//                .passwordEncoder(new StandardPasswordEncoder("username"));
//    }
//
//    @Bean
//    public SessionRegistry sessionRegistry() {
//        return new SessionRegistryImpl();
//    }
//
//    @Bean
//    public ConcurrentSessionControlAuthenticationStrategy concurrentSessionControlAuthenticationStrategy() {
//        ConcurrentSessionControlAuthenticationStrategy sessionControlAuthenticationStrategy = new ConcurrentSessionControlAuthenticationStrategy(sessionRegistry());
//        sessionControlAuthenticationStrategy.setExceptionIfMaximumExceeded(true);
//        sessionControlAuthenticationStrategy.setMaximumSessions(1);
//        return sessionControlAuthenticationStrategy;
//    }
//
//    @Bean
//    public HttpSessionEventPublisher servletListenerRegistrationBean() {
//        return new HttpSessionEventPublisher();
//    }
//
//
//    public static void main(String[] args) {
//        MessageDigest messageDigest = null;
//        try {
//            messageDigest = MessageDigest.getInstance("md5");
//            byte[] digest = messageDigest.digest(Utf8.encode("123" + "{username}"));
//            StringBuffer string = new StringBuffer("123" + "{username}");
//            try {
//                ByteBuffer e = Charset.forName("UTF-8").newEncoder().encode(CharBuffer.wrap(string));
//                System.out.println(e.limit());
//                System.out.println("arrays.string : " + Arrays.toString(e.array()));
//            } catch (CharacterCodingException e) {
//                e.printStackTrace();
//            }
//            System.out.println("digest . array :" + Arrays.toString(digest));
//            System.out.println(new String(Hex.encode(digest)));
//            byte[] bytes = Utf8.encode("123" + "{username}");
//            System.out.println("utf8.encode : " + Arrays.toString(bytes));
//            System.out.println(Integer.toBinaryString(240 & bytes[4]) + "\t" + ((240 & bytes[3]) >>> 4));
//            System.out.println(Integer.toBinaryString(240) + "\t" + Integer.toBinaryString(bytes[1]));
//            StringBuffer sb = new StringBuffer(new String(Hex.encode(digest)));
//            System.out.println(sb.toString());
//            System.out.println(new StandardPasswordEncoder("username").encode("123").length());
//            System.out.println(UUID.randomUUID().toString());
//        } catch (NoSuchAlgorithmException e) {
//            e.printStackTrace();
//        }
//
//    }
//}
